function draw_map(grid)

	tileset_batch:clear()

	local offX = dOX
	local offY = dOY
	local id

	tileset_batch:bind()

	for y = 1, range_y do
		for x = 1, range_x do
				if grid ~= nil then

					if grid[y+map_y] ~= nil then
						if grid[y+map_y][x+map_x] ~= nil then
							

							-- if grid location exists, assign associated tile
							id = tileset_batch:add(tile_quads[grid[y+map_y][x+map_x]],
								offX+(x*(tile_size*scale)),
								offY+(y*(tile_size*scale)), 0,
								scale, scale )
							tb_ids[id] = {}

							

							tb_ids[id].x = offX+(x*(tile_size*scale))
							tb_ids[id].y = offY+(y*(tile_size*scale))

						else
							-- otherwise show outer space
							id = tileset_batch:add(tile_quads[1],
								offX+(x*(tile_size*scale)),
								offY+(y*(tile_size*scale)), 0,
								scale, scale )

							tb_ids[id] = {}

							tb_ids[id].x = offX+(x*(tile_size*scale))
							tb_ids[id].y = offY+(y*(tile_size*scale))

						end

					else
						-- otherwise show outer space
						id = tileset_batch:add(tile_quads[1],
							offX+(x*(tile_size*scale)),
							offY+(y*(tile_size*scale)), 0,
							scale, scale )

						tb_ids[id] = {}

						tb_ids[id].x = offX+(x*(tile_size*scale))
						tb_ids[id].y = offY+(y*(tile_size*scale))

					end
				else
					-- otherwise show outer space
					id = tileset_batch:add(tile_quads[1],
						offX+(x*(tile_size*scale)),
						offY+(y*(tile_size*scale)), 0,
						scale, scale )

					tb_ids[id] = {}

					tb_ids[id].x = offX+(x*(tile_size*scale))
					tb_ids[id].y = offY+(y*(tile_size*scale))

				end

		end
	end

	tileset_batch:unbind()
	--print(table.tostring(tb_ids))


end

function draw_text(text)

	text = text .. ""

	con_text = text
	draw_con = true



end

function draw_bar(x, y, height, max_bar, current_bar, color1, color2, color3)
	
	love.graphics.setColor(255, 255, 255, 255)

	local color1 = color1 or {52, 135, 76, 255}
	local color2 = color2 or {255, 255, 50, 255}
	local color3 = color3 or {255, 0, 0, 255}
	local height = height or 10

	love.graphics.rectangle("line", x, y, 
		max_bar, height)	

	if current_bar > max_bar*0.75 then 
		love.graphics.setColor(color1[1], color1[2], color1[3], color1[4])
	elseif current_bar > max_bar*0.25 then
		love.graphics.setColor(color2[1], color2[2], color2[3], color2[4])
	else
		love.graphics.setColor(color3[1], color3[2], color3[3], color3[4])
	end

	love.graphics.rectangle("fill", x, y,
		current_bar, 10)
	love.graphics.setColor(255, 255, 255, 255)

end



function draw_hud()

	if draw_con then
		-- console print toggle

		love.graphics.print(con_text,
			console_x, console_y)

	end

	love.graphics.print(player.full_name,
		10, 10)

	--love.graphics.print(player.health,
		--10, 25)
	-- health bar
	draw_bar(10, 25, 10, 100, player.health/player.max_health*100)	

	-- battery bar
	draw_bar(10, 40, 10, 100, player.battery/player.max_bat*100,
		{91, 113, 255, 255}, {91, 113, 255, 255}, {91, 113, 255, 255} )

	-- scourge research bar
	love.graphics.print(player.res_lev,
		0, 55)
	draw_bar(10, 55, 10, 100, player.scourge_res/player.quota*100,
		{185, 255, 160, 255}, {185, 255, 160, 255}, {185, 255, 160, 255})

	--love.graphics.print(player.scourge_res,
	--	10, 40)

	--love.graphics.print(player.quota,
	--	10, 55)

	

	--love.graphics.print(player.battery,
	--	10, 85)	
	-- just to see splatter info, prolly remove before release
	love.graphics.print(player.splatters_cleaned,
		10, 70)

	love.graphics.print(collectgarbage('count'), 10, 85)




end

function msg_queue( msg, msg_opt )
	-- adds a message to be shown

	local id = #msgs+1

	msgs[id] = _navi:new(msg, msg_opt)

	msg_id = id

	print("msg id : ", msg_id, "msg :", msg)

end

function msg_queue_upd(dt)

	-- checks for old messages and removes them
	-- not currently needed as handled in msg_queue_draw()

	for i = 1, #msgs do

		if msgs[i]:is_over() then

			msgs[i] = nil
		end

	end

end

function msg_queue_draw()


	for i = 1, #msgs do

		if msgs[i] then


			if msgs[i]:is_over() then
				-- if msg is over, restore control to player
				-- and destroy message
				msgs[i] = nil
				player.lock_control = false
			end

			if msgs[i] then
				-- if a message is in the queue, play it
				-- control removed from player until message finished
				msgs[i]:play(msg_x, msg_y)
				player.lock_control = true
			end

		end


	end

end

function random_rotation()

	local r = RNG:random(360)
	local rad = r * (math.pi/180)
	return rad

end

function update_con(con_count)
	-- timer for displaying console messages
	-- edit con_time to change
	local con_time = 3

	if draw_con then

		con_count = con_count + 1

		if con_count >= love.timer.getFPS() * con_time then
			con_count = 0
			draw_con = false
		end

		return con_count
	end

	return con_count

end

function draw_group(group)

	-- draw x, y nested table elements
	-- presently just used for features (i think)

	for y = 1, range_y do
		for x = 1, range_x do
			if group[y+map_y] then
				if group[y+map_y][x+map_x] then	-- if it exists then draw it

					if group[y+map_y][x+map_x].t ~= "scourge" then -- is not scourge
						local rot = group[y+map_y][x+map_x].rotation
						local offX = group[y+map_y][x+map_x].offset_x
						local offY = group[y+map_y][x+map_x].offset_y
						if group[y+map_y][x+map_x].lit then -- flashlight?

							

							draw_light(group[y+map_y][x+map_x].image,
								dOX+(x*(tile_size*scale)),
								dOY+(y*(tile_size*scale)), rot,
								scale, scale, offX, offY)

							group[y+map_y][x+map_x].x = dOX+(x*(tile_size*scale))
							group[y+map_y][x+map_x].y = dOY+(y*(tile_size*scale))


						else

							draw_dark(group[y+map_y][x+map_x].image,
								dOX+(x*(tile_size*scale)),
								dOY+(y*(tile_size*scale)), rot,
								scale, scale, offX, offY)

							group[y+map_y][x+map_x].x = dOX+(x*(tile_size*scale))
							group[y+map_y][x+map_x].y = dOY+(y*(tile_size*scale))

						end
					else


						draw_dark(group[y+map_y][x+map_x].image,
							dOX+(x*(tile_size*scale)),
							dOY+(y*(tile_size*scale)), 0,
							scale, scale)
						group[y+map_y][x+map_x].x = dOX+(x*(tile_size*scale))
						group[y+map_y][x+map_x].y = dOY+(y*(tile_size*scale))

					end

				end

			end

		end

	end


end

function light_scene()

	Fog:set_seen_all( true )
	Feature:set_lit_all( true )
	Enemy:set_lit_all( true )
	Item:set_lit_all( true )

	SceneCompletelyLit = true

end

function draw_light(image, x, y, rotation, scaleX, scaleY, offX, offY)

	-- draw at full brightness

	image = image or nil
	x = x or 0
	y = y or 0
	rotation = rotation or 0
	scaleX = scaleX or scale
	scaleY = scaleY or scale
	offX = offX or 0
	offY = offY or 0

	love.graphics.setColor(255,255,255)
	love.graphics.draw(image,
		x,
		y, rotation,
		scaleX, scaleY, offX, offY)

end

function draw_dark(image, x, y, rotation, scaleX, scaleY, offX, offY)
	-- draw dim
	love.graphics.setColor(66,66,66)
	love.graphics.draw(image,
		x,
		y, rotation,
		scaleX, scaleY, offX, offY)

	love.graphics.setColor(255,255,255)

end

function update_animations(dt, anims)

	-- animation handler

	for i = #anims, 1, -1 do
		if anims[i].anim ~= nil then
			anims[i].anim:update(dt)
		end

	end


end

function draw_animations(anims)

	if #anims > 0 then
		--print(table.tostring(anims))
		for i = #anims, 1, -1 do
			if anims[i].anim ~= nil then

				if anims[i].anim.status ~= "paused" then

					if animations[anims[i].t](anims[i].t, anims[i]) then -- plays animation here
						--print("playing animation of type : ", anims[i].t)
					else
						--print(anims[i].t, ": invalid animation key")
					end
				else
					-- animation is done, clean up
					--print(anims[i].t, " paused, removing ")

					table.remove(anims, i)
				end
			end

		end

	end

end

function anim_cleanup(anims)

	-- extra cleanup for anims

	for i = #anims, 1, -1 do

		if anims[i].anim.status == "paused" then
			table.remove(anims, i)

		end

	end

	if #anims == 0 then
		anims = {}
	end

end

function draw_proj(proj)


	-- draw projectiles

	if #proj ~= nil then

		for i = 1, #proj do
			if proj[i] then
				if proj[i].visible == true then
					love.graphics.draw(proj[i].image, proj[i].x, proj[i].y)

				end
			end

		end

	end


end

function draw_entity(entity)

	-- draw a struct with .x and .y elements

	local scaledX = ((entity.x/tile_size)*scale)*tile_size
	local scaledY = ((entity.y/tile_size)*scale)*tile_size

	love.graphics.draw(entity.image, dOX+scaledX, dOY+scaledY)

end

function draw_player(player)

	-- player and flashlight lighting
	-- pX, pY represent the players position
	local pX = dOX+((player.range_x)*(tile_size*scale))/2+(tile_size/2)*scale
	local pY = dOY+((player.range_y)*(tile_size*scale))/2+(tile_size/2)*scale
	local mX, mY = love.mouse.getPosition()
	local aS = (3*math.pi)/2
	local aF = math.pi/2
	local dX = (mX-pX)
	local dY = (mY-pY)
	local pX2 = pX+((tile_size*scale)/2)
	local pY2 = pY+((tile_size*scale)/2)
	local mR = math.atan2(mY-pY2, mX-pX2)
	local hyp = math.sqrt((dX*dX)+(dY*dY))

	draw_held(player.body:getX(),
		player.body:getY(), player.body:getAngle())

	love.graphics.draw(player.image, player.body:getX(),
		player.body:getY(), player.body:getAngle()+(0.5*math.pi), scale/2, scale/2,
		player.image:getWidth()/2, player.image:getHeight()/2)


	

	love.graphics.setLineWidth(2)
	love.graphics.setLineStyle("smooth")
	--love.graphics.line(pX2, pY2, mX, mY)
	local mS = player.body:getAngle()
	mS = mS .. ""

	--love.graphics.print(mS, 10, 10)

	love.graphics.setColor(255, 0, 0)
	--love.graphics.circle("line", pX2, pY2, p_turret_rad, 100)
	love.graphics.setColor(255,255,255)




end

function draw_held(pX2, pY2, mR)

	-- if the light is on, draw it
	-- look at that fucked up math

	if player.light == true then

		love.graphics.draw(light_beam_img, (pX2),
			(pY2), mR, scale*4, scale*2, -(tile_size/8), (tile_size/2.75))
		love.graphics.draw(flashlight_img, (pX2),
			(pY2), mR, scale/2, scale/2, (tile_size), -(tile_size/3))

	end

	if player.mopping == true then
		love.graphics.draw(mop_img, (pX2),
			(pY2), mR-(0.5*math.pi), scale, scale/2, tile_size/6, -(tile_size/3))

	end

end
